﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.MediaCenter.UI;
using System.Diagnostics;
using MyVideoViewerLibrary;

namespace MyVideoViewerMCPlugin
{
    public class MovieGallery : GalleryPage
    {
        private IMoviesBusiness movieBl;

        private MyMovie currentMovie;
        public MyMovie CurrentMovie
        {
            get { return currentMovie; }
            set
            {
                if (currentMovie != value)
                {
                    currentMovie = value;
                    FirePropertyChanged("CurrentMovie");
                }
            }
        }

        List<MyMovie> movies = new List<MyMovie>();
        public List<MyMovie> Movies
        {
            get { return movies; }
        }

        public MovieGallery(List<MyMovie> moviesList)
        {
            PropertyChanged += new PropertyChangedEventHandler(SeriesGallery_PropertyChanged);
            ShowChangeItemSize = true;
            ItemSize = (GalleryItemSize)Enum.Parse(typeof(GalleryItemSize), MySettings.Default.MoviesItemSize, true);
            Description = "Movies";

            movies = moviesList;

            movieBl = MoviesBusiness.MoviesBL;

            VirtualList galleryList = new VirtualList(this, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompleteGalleryItem);
            Content = galleryList;

            CreateGalleryFilters();
        }

        void SeriesGallery_PropertyChanged(IPropertyObject sender, string property)
        {
            if (property == "ItemSize")
            {
                MySettings.Default.MoviesItemSize = ItemSize.ToString();
                MySettings.Default.Save();
            }
        }

        private void CreateGalleryFilters()
        {
            //
            // Put together a list of filters on the content.
            //

            ArrayListDataSet list = new ArrayListDataSet(this);
            foreach (CommandItem item in movieBl.GetFilterItems())
            {
                list.Add(new Filter(this, item.Description, (int) item.Data));
            }
            
                        
            Choice filters = new Choice(this, null, list);
            if(list.Count > 0)
                filters.Chosen = (ModelItem)list[0];

            //
            // Hook up the "filter changed" event so that we can apply the
            // active filter to our gallery.
            //
            // As soon as this Filters list is set, we will get an OnActiveFilterChanged
            // event which will cause us to populate the gallery.
            //

            ActiveFilterChanged += delegate(object sender, EventArgs e)
            {
                MovieGallery galleryPage = (MovieGallery)sender;
                Filter activeFilter = (Filter)galleryPage.Filters.Chosen;
                FilterContent(galleryPage, activeFilter.FilterId);
            };
            Filters = filters;
        }

        private void FilterContent(MovieGallery page, int filterId)
        {
            Content.Clear();

            FilterType filter = (FilterType)filterId;

            switch (filter)
            {
                case FilterType.ReleaseDate:
                    var r2 = page.Movies.Where(m=>m.ReleaseDate.HasValue).OrderBy(m => m.ReleaseDate).ThenBy(m => m.Title).GroupBy(t => t.ReleaseDate.Value.Date);
                    foreach (var result in r2)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(page.CreateGalleryItem(m, m.ReleaseDate.HasValue ? m.ReleaseDate.Value.ToString("MMM d, yyyy") : "", first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.MPAARating:
                    var r3 = page.Movies.OrderBy(m => m.Rating).ThenBy(m => m.Title).GroupBy(t => t.Rating);
                    foreach (var result in r3)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(page.CreateGalleryItem(m, m.Rating, first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.Genre:
                    var r4 = page.Movies.OrderBy(m => m.Genre).ThenBy(m => m.Title).GroupBy(t => t.Genre);
                    foreach (var result in r4)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(page.CreateGalleryItem(m, m.Genre, first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.Studio:
                    var r5 = page.Movies.OrderBy(m => m.Studio).ThenBy(m => m.Title).GroupBy(t => t.Studio);
                    foreach (var result in r5)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(page.CreateGalleryItem(m, m.Studio, first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.LastAdded:
                    var r7 = page.Movies.Where(m=>m.MovieTitle.DateAdded.HasValue).OrderByDescending(m => m.MovieTitle.DateAdded).ThenBy(m => m.Title).GroupBy(m => m.MovieTitle.DateAdded.Value.Date);
                    foreach (var result in r7)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(page.CreateGalleryItem(m, m.MovieTitle.DateAdded.HasValue ? m.MovieTitle.DateAdded.Value.ToString("MMM d, yyyy") : "", first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.Watched:
                    var r8 = page.Movies.Where(m => m.MovieTitle.Watched).OrderBy(m => m.SortTitle);
                    foreach (MyMovie m in r8)
                        page.Content.Add(page.CreateGalleryItem(m, "", false));
                    break;
                case FilterType.NotWatched:
                    var r9 = page.Movies.Where(m => !m.MovieTitle.Watched).OrderBy(m => m.SortTitle);
                    foreach (MyMovie m in r9)
                        page.Content.Add(page.CreateGalleryItem(m, "", false));
                    break;
                case FilterType.Rating:
                    var r10 = page.Movies.OrderByDescending(m => m.MovieTitle.Rating).ThenBy(m => m.Title).GroupBy(t => t.MovieTitle.Rating);
                    foreach (var result in r10)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(page.CreateGalleryItem(m, m.MovieTitle.Rating.HasValue ? m.MovieTitle.Rating.Value.ToString() : "", first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.Runtime:
                    var r11 = page.Movies.OrderBy(m => m.MovieTitle.Runtime).ThenBy(m => m.Title).GroupBy(t => t.MovieTitle.Runtime);
                    foreach (var result in r11)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(page.CreateGalleryItem(m, m.MovieTitle.Runtime.ToString(), first));
                            first = false;
                        }
                    }
                    break;
                default:
                    var r6 = page.Movies.OrderBy(m => m.SortTitle);
                    foreach (MyMovie m in r6)
                        page.Content.Add(page.CreateGalleryItem(m, "", false));
                    break;
            }

            //
            // Populate the list with items according to the filter.
            //
            //sList<MyMovie> temp = null;
            
        }

        internal ThumbnailCommand CreateGalleryItem(MyMovie movieData, string description, bool isHeading)
        {
            ThumbnailCommand item = new ThumbnailCommand(this);
            item.Description = movieData.Title;
            item.Data = movieData;
            item.ShowHeading = isHeading;
            item.Metadata = description;
            //
            // Hook up an event for when the gallery item is invoked.
            //

            item.Invoked += delegate(object sender, EventArgs args)
            {
                ThumbnailCommand galleryItem = (ThumbnailCommand)sender;

                MyMovie movie = (MyMovie)galleryItem.Data;
                //MyMoviesBrowserLibrary.MyMoviesBrowserBusiness.MarkMovieAsWatched(movie.MovieTitle, true);
                Application.Current.GoToDetailsPage((MyMovie)galleryItem.Data);
            };

            item.OnFocus += delegate(object sender, EventArgs args)
            {
                ThumbnailCommand galleryItem = (ThumbnailCommand)sender;

                MovieGallery page = (MovieGallery)galleryItem.Owner;
                page.CurrentMovie = (MyMovie)galleryItem.Data;
            };

            return item;
        }

        public override int JumpTo(string searchText)
        {
            searchText = searchText.ToLower();
            List<MyMovie> temp = Content.Cast<ThumbnailCommand>().Select(t => t.Data).Cast<MyMovie>().ToList();
            List<MyMovie> temp2 = new List<MyMovie>();
            do
            {
                temp2 = (from m in temp
                         where m.SortTitle.ToLower().StartsWith(searchText)
                         select m).ToList();
                if (searchText.Length > 0)
                    searchText = searchText.Substring(0, searchText.Length - 1);
            } while (temp2.Count == 0 && searchText.Length > 0);

            if (temp2.Count > 0)
            {
                int i = temp.IndexOf(temp2.First());
                return i;
            }
            return -1;
        }

        #region slowdatahandlers
        /// <summary>
        /// Finishes any slow data for a gallery item.
        /// </summary>
        protected void CompleteGalleryItem(VirtualList list, int index)
        {
            ThumbnailCommand item = (ThumbnailCommand)list[index];
            CompleteGalleryItem(item, (MyMovie)item.Data);
        }

        /// <summary>
        /// Finishes any slow data for a gallery item.
        /// </summary>
        protected void CompleteGalleryItem(ThumbnailCommand item, MyMovie myMovieData)
        {
            string imageName = "file://" + myMovieData.FolderImage;
            item.Image = LoadImage(imageName);
        }
        #endregion
    }
}
